home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / gdb / gdb_18s.zoo / utils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-27  |  10.6 KB  |  492 lines

  1. /* General utility routines for GDB, the GNU debugger.
  2.    Copyright (C) 1986 Free Software Foundation, Inc.
  3.  
  4. GDB is distributed in the hope that it will be useful, but WITHOUT ANY
  5. WARRANTY.  No author or distributor accepts responsibility to anyone
  6. for the consequences of using it or for whether it serves any
  7. particular purpose or works at all, unless he says so in writing.
  8. Refer to the GDB General Public License for full details.
  9.  
  10. Everyone is granted permission to copy, modify and redistribute GDB,
  11. but only under the conditions described in the GDB General Public
  12. License.  A copy of this license is supposed to have been given to you
  13. along with GDB so you can know your rights and responsibilities.  It
  14. should be in a file named COPYING.  Among other things, the copyright
  15. notice and this notice must be preserved on all copies.
  16.  
  17. In other words, go ahead and share GDB, but don't try to stop
  18. anyone else from sharing it farther.  Help stamp out software hoarding!
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <signal.h>
  23.  
  24. #ifdef atarist
  25. #include <ioctl.h>
  26. #else
  27. #include <sys/ioctl.h>
  28. #endif
  29.  
  30. #include "defs.h"
  31. #include "param.h"
  32. #ifdef HAVE_TERMIO
  33. #include <termio.h>
  34. #endif
  35.  
  36. void error ();
  37. void fatal ();
  38.  
  39. /* Chain of cleanup actions established with make_cleanup,
  40.    to be executed if an error happens.  */
  41.  
  42. static struct cleanup *cleanup_chain;
  43.  
  44. /* Nonzero means a quit has been requested.  */
  45.  
  46. int quit_flag;
  47.  
  48. /* Nonzero means quit immediately if Control-C is typed now,
  49.    rather than waiting until QUIT is executed.  */
  50.  
  51. int immediate_quit;
  52.  
  53. /* Add a new cleanup to the cleanup_chain,
  54.    and return the previous chain pointer
  55.    to be passed later to do_cleanups or discard_cleanups.
  56.    Args are FUNCTION to clean up with, and ARG to pass to it.  */
  57.  
  58. struct cleanup *
  59. make_cleanup (function, arg)
  60.      void (*function) ();
  61.      int arg;
  62. {
  63.   register struct cleanup *new
  64.     = (struct cleanup *) xmalloc (sizeof (struct cleanup));
  65.   register struct cleanup *old_chain = cleanup_chain;
  66.  
  67.   new->next = cleanup_chain;
  68.   new->function = function;
  69.   new->arg = arg;
  70.   cleanup_chain = new;
  71.  
  72.   return old_chain;
  73. }
  74.  
  75. /* Discard cleanups and do the actions they describe
  76.    until we get back to the point OLD_CHAIN in the cleanup_chain.  */
  77.  
  78. void
  79. do_cleanups (old_chain)
  80.      register struct cleanup *old_chain;
  81. {
  82.   register struct cleanup *ptr;
  83.   while ((ptr = cleanup_chain) != old_chain)
  84.     {
  85.       cleanup_chain = ptr->next;    /* Do this first incase recursion */
  86.       (*ptr->function) (ptr->arg);
  87.       free (ptr);
  88.     }
  89. }
  90.  
  91. /* Discard cleanups, not doing the actions they describe,
  92.    until we get back to the point OLD_CHAIN in the cleanup_chain.  */
  93.  
  94. void
  95. discard_cleanups (old_chain)
  96.      register struct cleanup *old_chain;
  97. {
  98.   register struct cleanup *ptr;
  99.   while ((ptr = cleanup_chain) != old_chain)
  100.     {
  101.       cleanup_chain = ptr->next;
  102.       free (ptr);
  103.     }
  104. }
  105.  
  106. /* This function is useful for cleanups.
  107.    Do
  108.  
  109.      foo = xmalloc (...);
  110.      old_chain = make_cleanup (free_current_contents, &foo);
  111.  
  112.    to arrange to free the object thus allocated.  */
  113.  
  114. void
  115. free_current_contents (location)
  116.      char **location;
  117. {
  118.   free (*location);
  119. }
  120.  
  121. /* Generally useful subroutines used throughout the program.  */
  122.  
  123. /* Like malloc but get error if no storage available.  */
  124.  
  125. char *
  126. xmalloc (size)
  127.      long size;
  128. {
  129.   register char *val;
  130.   if(size == 0)
  131.       return NULL;
  132.   
  133.   val = (char *) malloc (size);
  134.   if (!val)
  135.     fatal ("virtual memory exhausted.", 0);
  136.   return val;
  137. }
  138.  
  139. /* Like realloc but get error if no storage available.  */
  140.  
  141. char *
  142. xrealloc (ptr, size)
  143.      char *ptr;
  144.      long size;
  145. {
  146.   register char *val = (char *) realloc (ptr, size);
  147.   if (!val)
  148.     fatal ("virtual memory exhausted.", 0);
  149.   return val;
  150. }
  151.  
  152. /* Print the system error message for errno, and also mention STRING
  153.    as the file name for which the error was encountered.
  154.    Then return to command level.  */
  155.  
  156. void
  157. perror_with_name (string)
  158.      char *string;
  159. {
  160.   extern int sys_nerr;
  161.   extern char *sys_errlist[];
  162.   extern int errno;
  163.   char *err;
  164.   char *combined;
  165.  
  166. #if 0 /* def atarist */
  167.   if (errno > sys_nerr)
  168. #else
  169.   if (errno < sys_nerr)
  170. #endif
  171.     err = sys_errlist[errno];
  172.   else
  173.     err = "unknown error";
  174.  
  175.   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
  176.   strcpy (combined, string);
  177.   strcat (combined, ": ");
  178.   strcat (combined, err);
  179.  
  180.   errno = 0;
  181.   error ("%s.", combined);
  182. }
  183.  
  184. /* Print the system error message for ERRCODE, and also mention STRING
  185.    as the file name for which the error was encountered.  */
  186.  
  187. void
  188. print_sys_errmsg (string, errcode)
  189.      char *string;
  190.      int errcode;
  191. {
  192.   extern int sys_nerr;
  193.   extern char *sys_errlist[];
  194.   char *err;
  195.   char *combined;
  196.  
  197. #if 0 /* def atarist */
  198.   if (errcode > sys_nerr)
  199. #else
  200.   if (errcode < sys_nerr)
  201. #endif
  202.     err = sys_errlist[errcode];
  203.   else
  204.     err = "unknown error";
  205.  
  206.   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
  207.   strcpy (combined, string);
  208.   strcat (combined, ": ");
  209.   strcat (combined, err);
  210.  
  211.  printf_filtered ("%s.\n", combined);
  212. }
  213.  
  214. void
  215. quit ()
  216. {
  217.   fflush (stdout);
  218. #ifdef HAVE_TERMIO
  219.   ioctl (fileno (stdout), TCFLSH, 1);
  220. #else /* not HAVE_TERMIO */
  221. #ifndef atarist
  222.   ioctl (fileno (stdout), TIOCFLUSH, 0);
  223. #endif
  224. #endif /* not HAVE_TERMIO */
  225. #if defined (TIOCGPGRP) || defined (atarist)
  226.   error ("Quit");
  227. #else
  228.   error ("Quit (expect signal %d when inferior is resumed)", SIGINT);
  229. #endif /* TIOCGPGRP */
  230. }
  231.  
  232. /* Control C comes here */
  233.  
  234. void
  235. request_quit ()
  236. {
  237.   quit_flag = 1;
  238.   if (immediate_quit)
  239.     quit ();
  240. }
  241.  
  242. /* Print an error message and return to command level.
  243.    STRING is the error message, used as a fprintf_filtered string,
  244.    and ARG is passed as an argument to it.  */
  245.  
  246. void
  247. error (string, arg1, arg2, arg3)
  248.      char *string;
  249.      int arg1, arg2, arg3;
  250. {
  251.   fflush (stdout);
  252.   fprintf_filtered (stderr, "\n");
  253.   fprintf_filtered (stderr, string, arg1, arg2, arg3);
  254.   fprintf_filtered (stderr, "\n");
  255.   return_to_top_level ();
  256. }
  257.  
  258. /* Print an error message and exit reporting failure.
  259.    This is for a error that we cannot continue from.
  260.    STRING and ARG are passed to fprintf_filtered.  */
  261.  
  262. void
  263. fatal (string, arg)
  264.      char *string;
  265.      int arg;
  266. {
  267.   extern void really_exit();
  268.  
  269.   fprintf_filtered (stderr, "gdb: ");
  270.   fprintf_filtered (stderr, string, arg);
  271.   fprintf_filtered (stderr, "\n");
  272.   really_exit (1);
  273. }
  274.  
  275. /* Make a copy of the string at PTR with SIZE characters
  276.    (and add a null character at the end in the copy).
  277.    Uses malloc to get the space.  Returns the address of the copy.  */
  278.  
  279. char *
  280. savestring (ptr, size)
  281.      char *ptr;
  282.      int size;
  283. {
  284.   register char *p = (char *) xmalloc (size + 1);
  285.   bcopy (ptr, p, size);
  286.   p[size] = 0;
  287.   return p;
  288. }
  289.  
  290. char *
  291. concat (s1, s2, s3)
  292.      char *s1, *s2, *s3;
  293. {
  294.   register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
  295.   register char *val = (char *) xmalloc (len);
  296.   strcpy (val, s1);
  297.   strcat (val, s2);
  298.   strcat (val, s3);
  299.   return val;
  300. }
  301.  
  302. void
  303. print_spaces (n, file)
  304.      register int n;
  305.      register FILE *file;
  306. {
  307.   while (n-- > 0)
  308.     fputc_filtered (' ', file);
  309. }
  310.  
  311. /* Ask user a y-or-n question and return 1 iff answer is yes.
  312.    Takes three args which are given to printf to print the question.
  313.    The first, a control string, should end in "? ".
  314.    It should not say how to answer, because we do that.  */
  315.  
  316. int
  317. query (ctlstr, arg1, arg2)
  318.      char *ctlstr;
  319. {
  320.   register int answer;
  321.  
  322.   /* Automatically answer "yes" if input is not from a terminal.  */
  323.   if (!input_from_terminal_p ())
  324.     return 1;
  325.  
  326.   while (1)
  327.     {
  328.      printf(ctlstr, arg1, arg2);
  329.      printf ("(y or n) ");
  330.       fflush (stdout);
  331.       answer = fgetc (stdin);
  332.       clearerr (stdin);        /* in case of C-d */
  333.       if (answer == EOF)    /* C-d */
  334.         return 1;
  335.       if (answer != '\n')
  336.     while (fgetc (stdin) != '\n') clearerr (stdin);
  337.       if (answer >= 'a')
  338.     answer -= 040;
  339.       if (answer == 'Y')
  340.     return 1;
  341.       if (answer == 'N')
  342.     return 0;
  343.      printf ("Please answer y or n.\n");
  344.     }
  345. }
  346.  
  347. /* Parse a C escape sequence.  STRING_PTR points to a variable
  348.    containing a pointer to the string to parse.  That pointer
  349.    is updated past the characters we use.  The value of the
  350.    escape sequence is returned.
  351.  
  352.    A negative value means the sequence \ newline was seen,
  353.    which is supposed to be equivalent to nothing at all.
  354.  
  355.    If \ is followed by a null character, we return a negative
  356.    value and leave the string pointer pointing at the null character.
  357.  
  358.    If \ is followed by 000, we return 0 and leave the string pointer
  359.    after the zeros.  A value of 0 does not mean end of string.  */
  360.  
  361. int
  362. parse_escape (string_ptr)
  363.      char **string_ptr;
  364. {
  365.   register int c = *(*string_ptr)++;
  366.   switch (c)
  367.     {
  368.     case 'a':
  369.       return '\a';
  370.     case 'b':
  371.       return '\b';
  372.     case 'e':
  373.       return 033;
  374.     case 'f':
  375.       return '\f';
  376.     case 'n':
  377.       return '\n';
  378.     case 'r':
  379.       return '\r';
  380.     case 't':
  381.       return '\t';
  382.     case 'v':
  383.       return '\v';
  384.     case '\n':
  385.       return -2;
  386.     case 0:
  387.       (*string_ptr)--;
  388.       return 0;
  389.     case '^':
  390.       c = *(*string_ptr)++;
  391.       if (c == '\\')
  392.     c = parse_escape (string_ptr);
  393.       if (c == '?')
  394.     return 0177;
  395.       return (c & 0200) | (c & 037);
  396.       
  397.     case '0':
  398.     case '1':
  399.     case '2':
  400.     case '3':
  401.     case '4':
  402.     case '5':
  403.     case '6':
  404.     case '7':
  405.       {
  406.     register int i = c - '0';
  407.     register int count = 0;
  408.     while (++count < 3)
  409.       {
  410.         if ((c = *(*string_ptr)++) >= '0' && c <= '7')
  411.           {
  412.         i *= 8;
  413.         i += c - '0';
  414.           }
  415.         else
  416.           {
  417.         (*string_ptr)--;
  418.         break;
  419.           }
  420.       }
  421.     return i;
  422.       }
  423.     default:
  424.       return c;
  425.     }
  426. }
  427.  
  428. void
  429. printchar (ch, stream)
  430.      unsigned char ch;
  431.      FILE *stream;
  432. {
  433.   register int c = ch;
  434.   if (c < 040 || c >= 0177)
  435.     {
  436.       if (c == '\n')
  437.     fprintf_filtered (stream, "\\n");
  438.       else if (c == '\b')
  439.     fprintf_filtered (stream, "\\b");
  440.       else if (c == '\t')
  441.     fprintf_filtered (stream, "\\t");
  442.       else if (c == '\f')
  443.     fprintf_filtered (stream, "\\f");
  444.       else if (c == '\r')
  445.     fprintf_filtered (stream, "\\r");
  446.       else if (c == 033)
  447.     fprintf_filtered (stream, "\\e");
  448.       else if (c == '\a')
  449.     fprintf_filtered (stream, "\\a");
  450.       else
  451.     fprintf_filtered (stream, "\\%03o", c);
  452.     }
  453.   else
  454.     {
  455.       if (c == '\\' || c == '"' || c == '\'')
  456.     fputc_filtered ('\\', stream);
  457.       fputc_filtered (c, stream);
  458.     }
  459. }
  460. #ifdef atarist
  461. #define IS_SPACE(c) (((c) == ' ') || ((c) == '\t'))
  462. #define IS_DIGIT(c) (((c) >= '0') && ((c) <= '9'))
  463.  
  464. /* dont use the fancy lib one */
  465. int atoi(s)
  466. char *s;
  467. {
  468.     int res = 0;
  469.     int mul = 1;
  470.     
  471.     if(!s)
  472.     return 0;
  473.     
  474.     while(IS_SPACE(*s)) s++;
  475.     if(*s == '+')
  476.     s++;
  477.     else if(*s == '-')
  478.     {
  479.     mul = -1;
  480.     s++;
  481.     }
  482.     
  483.     while(IS_DIGIT(*s))
  484.     {
  485.     res = (res * 10) + (*s - '0');
  486.     s++;
  487.     }
  488.  
  489.     return res * mul;
  490. }
  491. #endif
  492.